import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
df=pd.read_csv('H:\VS Code\淘宝用户购物行为数据可视化分析\淘宝用户购物行为数据集_清洗后.csv')
pv=len(df)#总行为次数
uv=df['用户ID'].nunique()#总用户数
pv_per_uv=pv/uv#平均每用户访问深度


#分行为类型统计
behavior_stats=df.groupby('行为名称').agg(
    PV=('用户ID','count'),
    UV=('用户ID','nunique')
).reset_index()
print(f"""
总PV：{pv:,}
总UV：{uv:,}
每个用户平均访问深度：{pv_per_uv:.1f}"""
)
print(behavior_stats.head())
'''业务解读：
1.若PV/UV>10，说明用户深度浏览
2.购买行为的UV/PV比反映转化效率'''


#时间维度流量趋势
#按小时统计
hourly=df.groupby('小时段').agg(
    PV=('用户ID','count'),
    UV=('用户ID','nunique')
).reset_index()
print(hourly.head(24))

#24小时热力图
fig=px.density_heatmap(df,x='小时段',y='星期',
    z='用户ID',histfunc='count',title='24小时流量分布')
fig.update_layout(yaxis={'categoryorder':'array','categoryarray':['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']})
#fig.show()
#由热力图得出：
#每日高峰时段为20:00至23:00
#1.周一至周五的流量最高，周日最低
#2.早上和晚上的流量最高，中午和晚上的流量最低
#3.周一至周五的流量基本稳定，周六至周日的流量基本稳定
#4.早上和晚上的流量基本稳定，中午和晚上的流量基本稳定
#5.周一至周五的流量基本稳定，周六至周日的流量基本稳定
#6.早上和晚上的流量基本稳定，中午和晚上的流量基本稳定



#流量新增渠道字段（模拟数据）
df['渠道']= pd.cut(df['用户ID']%100,bins=[0,30,60,100],labels=['自然流量','广告投放','社会引流'])
#各渠道质量分析
channel_quality=df.groupby('渠道').agg(
    PV=('用户ID','count'),
    UV=('用户ID','nunique'),
    转化率=('行为类型',lambda x: (x==4).mean())
).sort_values('转化率',ascending=False)#按照转化率降序排列

#流量-转化关联分析
conversion_users=df[df['行为类型']==4]['用户ID'].unique()#转化用户
df['是否转化']=df['用户ID'].isin(conversion_users)
#转化用户VS未转化用户的流量特征对比
traffic_comparision=df.groupby('是否转化').agg(
    avg_pv=('用户ID','count'),
    avg_session=('日期',lambda x:x.unique()),
    favorite_hour=('小时段',lambda x:x.mode()[0])
).T


###24小时流量曲线图（带交互功能）
#数据准备
hourly_stats= df.groupby('小时段').agg(
    PV=('用户ID','count'),
    UV=('用户ID','nunique'),
    转化率=('行为类型',lambda x:(x==4).mean()*100)#转为百分比
).reset_index()
#创建双轴图表
fig=make_subplots(specs=[[{'secondary_y':True}]])
#添加PV/UV柱状图
fig.add_trace(
    go.Bar(
        x=hourly_stats['小时段'],
        y=hourly_stats['PV'],
        name='PV',
        marker_color='#636EFA',
        opacity=0.7,
        hovertemplate="时间：%{x}:00<bar>PV:%{y:,}<extra></extra>"
    ),
    secondary_y=False
)
# 添加UV线图
fig.add_trace(
    go.Scatter(
        x=hourly_stats['小时段'],
        y=hourly_stats['UV'],
        name='UV',
        line=dict(color='#FFA15A', width=3),
        mode='lines+markers',
        hovertemplate="时间: %{x}:00<br>UV: %{y:,}<extra></extra>"
    ),
    secondary_y=False
)

# 添加转化率线图
fig.add_trace(
    go.Scatter(
        x=hourly_stats['小时段'],
        y=hourly_stats['转化率'],
        name='转化率',
        line=dict(color='#00CC96', width=3, dash='dot'),
        mode='lines+markers',
        hovertemplate="时间: %{x}:00<br>转化率: %{y:.1f}%<extra></extra>"
    ),
    secondary_y=True
)
# 图表装饰
fig.update_layout(
    title='24小时流量趋势分析（PV/UV vs 转化率）',
    xaxis=dict(
        title='小时',
        tickvals=list(range(24))),
    yaxis=dict(
        title='PV/UV数量',
        rangemode='tozero'),
    yaxis2=dict(
        title='转化率 (%)',
        overlaying='y',
        side='right',
        
range=[0, hourly_stats['转化率'].max()*1.2]),
    hovermode='x unified',
    template='plotly_white'
)


# 添加业务注释
fig.add_vrect(
    x0=19, x1=22,
    fillcolor="red", opacity=0.1,
    annotation_text="黄金时段", annotation_position="top left"
)

###渠道质量雷达图（三维指标对比）
#假设已计算渠道数据（示例数据）
channel_data={
    '渠道':['自然流量','广告投放','社会引流'],
    'PV':[1000,500,200],
    'UV':[200,300,400],
    '转化率':[0.1,0.2,0.3]
}
channel_df=pd.DataFrame(channel_data)

#数据标准化（0-1）范围
channel_df['PV_norm'] = channel_df['PV'] / channel_df['PV'].max()
channel_df['UV_norm'] = channel_df['UV'] / channel_df['UV'].max()
channel_df['转化率_norm'] = channel_df['转化率'] / channel_df['转化率'].max()
fig=go.Figure()
for i in range(len(channel_df)):
    fig.add_trace(go.Scatterpolar(
        r=[
            channel_df.loc[i,'PV_norm'],
            channel_df.loc[i,'UV_norm'],
            channel_df.loc[i,'转化率_norm'],
            channel_df.loc[i,'PV_norm']
        ],
        theta=['PV','UV','转化率','PV'],
        name=channel_df.loc[i,'渠道'],
        fill='toself',#填充区域
        line=dict(width=2),
        hovertemplate=
        f"<b>{channel_df.loc[i,'渠道']}</b><br>"+
        f"PV:{channel_df.loc[i,'PV']:,}<br>"+
        f"UV:{channel_df.loc[i,'UV']:,}<br>"+
        f"转化率:{channel_df.loc[i,'转化率']*100:.1f}<extra></extra>"
    ))


# 图表装饰
fig.update_layout(
    title='渠道质量三维对比雷达图',
    polar=dict(
        radialaxis=dict(
            visible=True,
            range=[0, 1],
            tickvals=[0.2, 0.4, 0.6, 0.8, 1],
            ticktext=['20%', '40%', '60%', '80%', '100%'])
    ),
    showlegend=True,
    template='plotly_dark',
    hoverlabel=dict(
        bgcolor="white",
        font_size=12,
        font_family="Arial"
    )
)

# 添加平均线参考
fig.add_trace(go.Scatterpolar(
    r=[0.5, 0.5, 0.5, 0.5],
    theta=['PV', 'UV', '转化率', 'PV'],
    name='平均水平',
    line=dict(color='white', dash='dot'),
    hoverinfo='none'
))
fig.show()